package com.hsd.netty.server.strategy;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.hsd.netty.server.common.NettyHeader;
import com.hsd.netty.server.common.NettyMessage;
import com.hsd.netty.server.enums.MessageCode;
import io.netty.channel.ChannelHandlerContext;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author s.he
 * on 2020/6/1
 */
public abstract class MessageTypeHandler {
    private static final Logger logger = LoggerFactory.getLogger(MessageTypeHandler.class);

    static final List<String> blackIPAddress = Arrays.asList("127.0.0.1", "192.168.2.246");

    static Cache<String, String> loginInfoMap = CacheBuilder.newBuilder().maximumSize(100)
            .concurrencyLevel(10).recordStats().expireAfterWrite(60, TimeUnit.MINUTES).build();


    /**
     * 不同类型不同处理方式
     * @param channelHandlerContext
     * @param nettyMessage
     * @return
     */
     abstract NettyMessage handler(ChannelHandlerContext channelHandlerContext, NettyMessage nettyMessage);


     public NettyMessage loginFilter(ChannelHandlerContext channelHandlerContext, NettyMessage nettyMessage) {
         logger.info("【登录鉴权拦截】");
         NettyMessage result = new NettyMessage();
         NettyHeader header = null;
         InetSocketAddress socketAddress = (InetSocketAddress)channelHandlerContext.channel().remoteAddress();
         String hostAddress = socketAddress.getAddress().getHostAddress();
         long sessionId = nettyMessage.getNettyHeader().getSessionId();

         if(!blackIPAddress.contains(hostAddress)) {
             header = new NettyHeader();
             header.setStatusCode(MessageCode.NOT_AUTH.getCode());
             header.setType(nettyMessage.getNettyHeader().getType());
             result.setNettyHeader(header);
             return result;
         }
         String ifPresent = loginInfoMap.getIfPresent(hostAddress);
         if(!StringUtils.equalsIgnoreCase(ifPresent, String.valueOf(sessionId))) {
             header = new NettyHeader();
             header.setStatusCode(MessageCode.AUTH_ERROR.getCode());
             header.setType(nettyMessage.getNettyHeader().getType());
             result.setNettyHeader(header);
             return result;
         }
         return result;
     }
}
